package workgroup.osaka.DirectLink;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;

//ファイルの受信
public class FileServerAsyncTask extends AsyncTask<Void, Void, String>{

	private Context context;
	private DirectLinkMainActivity activity;
	static ServerSocket IPSocket = null;
	static ServerSocket serverSocket = null;

	private boolean isOwner = false;
	
	public FileServerAsyncTask(Context context , DirectLinkMainActivity activity , boolean isOwner) {
		this.context = context;
		this.activity = activity;
		this.isOwner = isOwner;
		Log.d("受信１", "コンストラクタ");
	}

	@Override
	protected String doInBackground(Void... params) {
		
		if(isOwner){
			try {
				//受信用のソケットを8989番portで準備①
				IPSocket = new ServerSocket(8989);
				Log.d("受信A", "Server: Socket opened");

				//作成したソケットで受信待ち②
				Log.d("受信B", "受信待ち");
				Socket client = IPSocket.accept(); 
				Log.d("受信C","Server: connection done");
				//⑥

				//受信用の通信路を準備
				InputStream inputstream = client.getInputStream();
				Log.d("受信D", "受信用の通信路を準備");

				//受信してClientIPをセット
				CientIP(inputstream);
				Log.d("受信E", "受信してClientIPをセット");
				
				//受信に利用したソケットのclose⑫
				IPSocket.close();
				Log.d("受信F", "受信に利用したソケットのclose");
				
			} catch (IOException e) {
				Log.e("受信エラー", e.getMessage());
				return null;
			}
		}
		try {
			//受信用のソケットを8988番portで準備①
			serverSocket = new ServerSocket(8988);
			
			Log.d("受信２", "Server: Socket opened");

			//作成したソケットで受信待ち②
			Log.d("受信３", "受信３");
			Socket client = serverSocket.accept(); 
			Log.d("受信４", "Server: connection done");
			//⑥

			//出力ファイルの絶対PATHを設定
			final File f = new File(Environment.getExternalStorageDirectory() + "/"
					+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
					+ ".jpg");
			Log.d("受信５－１", "ファイル作成："+ f.getName());
			Log.d("受信５－１", "ファイル作成："+ f.getPath());

			//出力ファイルの作成準備
			File dirs = new File(f.getParent());
			Log.d("受信５－２", "ファイル作成");

			//ディレクトリが無ければ作成？
			if (!dirs.exists())
				dirs.mkdirs();
			Log.d("受信５－３", "ディレクトリ作成");

			//出力ファイルを作成？⑨
			f.createNewFile();
			Log.d("受信６", "server: copying files " + f.toString());

			//受信用の通信路を準備
			InputStream inputstream = client.getInputStream();
			Log.d("受信７", "受信用の通信路を準備");

			//受信して出力ファイルに書き出す⑩
			copyFile(inputstream, new FileOutputStream(f));

			Log.d("受信８", "受信して出力ファイルに書き出す");

			//受信に利用したソケットのclose⑫
			serverSocket.close();
			Log.d("受信９", "受信に利用したソケットのclose");

			//使用したファイルの絶対PATHを返す
			return f.getAbsolutePath();
		} catch (IOException e) {
			Log.e("受信エラー", e.getMessage());
			return null;
		}
	}

	//受信した画像ファイルをアクションビューで表示
	@Override
	protected void onPostExecute(String result) {
		if (result != null) {
			Log.d("受信onPostExecute", "File copied - " + result);
			activity.DisplayPicture(result);
		}else{
			Log.d("受信onPostExecute", "result = " + result);
		}
	}

	//不要？
	@Override
	protected void onPreExecute() {
		Log.d("受信onPreExecute", "Opening a server socket");
		//statusText.setText("Opening a server socket");
	}

	//ファイル書き込みの際に使用
	private boolean copyFile(InputStream inputStream, OutputStream out) {
		byte buf[] = new byte[1024];
		int len;
		try {
			while ((len = inputStream.read(buf)) != -1) {
				out.write(buf, 0, len);
			}
			out.close();
			inputStream.close();
		} catch (IOException e) {
			Log.e("書き込み", e.toString());
			return false;
		}
		return true;
	}
	
	//クライアントＩＰ取得の際に使用
	private boolean CientIP(InputStream inputStream) {
		byte buf[] = new byte[1024];
		try {
			Log.d("CientIP", "クライアントＩＰ取得");
			buf = readAll(inputStream);
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		try {
			WiFiDirect.ClientIP  = new String(buf, "UTF-8"); 
			Log.d("クライアントＩＰ取得", WiFiDirect.ClientIP);
			isOwner = false;
			Log.d("CientIP","isOwner = " + isOwner);
			inputStream.close();
		} catch (IOException e) {
			Log.e("書き込みエラー", e.toString());
			return false;
		}
		return true;
	}
	
	//受信した inputStream のデータを byte[] にして return する
	public byte[] readAll(InputStream inputStream) throws IOException {
	    ByteArrayOutputStream bout = new ByteArrayOutputStream();
	    byte [] buffer = new byte[1024];
	    while(true) {
	        int len = inputStream.read(buffer);
	        if(len < 0) {
	            break;
	        }
	        bout.write(buffer, 0, len);
	    }
	    return bout.toByteArray();
	}

	//受信待ちしているソケットを閉じる
	public static void close(){
		if (IPSocket != null) {
			Log.d("close()", "受信に利用したIPソケットのclose");
			try {
				IPSocket.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			IPSocket = null;
		}
		if (serverSocket != null) {
			Log.d("close()", "受信に利用したサーバーソケットのclose");
			try {
				serverSocket.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			serverSocket = null;
		}
		
	}
}